package com.sike.config;


import co.elastic.clients.elasticsearch.ElasticsearchAsyncClient;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.SSLContexts;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.net.ssl.SSLContext;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;

@Configuration
public class ElasticSearchConfig {

    @Value("${es.hostname}")
    private String hostname;

    @Value("${es.port}")
    private int port;

    //注入IOC容器
    @Bean
    public ElasticsearchClient elasticsearchClient() throws Exception{
        final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        // 声明ES当前登录的账号密码
        credentialsProvider.setCredentials(AuthScope.ANY,new UsernamePasswordCredentials("elastic","4DBHt=M7jxlXDlU47e3F"));
        // 证书的路径
        Path caCertificatePath = Paths.get("E:\\idea_soft\\es8ssl\\src\\main\\resources\\http_ca.crt");
        // x.509 , pkcs12都是 证书的算法
        CertificateFactory factory = CertificateFactory.getInstance("x.509");
        Certificate trustedCa;
        try (InputStream is = Files.newInputStream(caCertificatePath)){
            trustedCa = factory.generateCertificate(is);
        }
        KeyStore trustStore = KeyStore.getInstance("pkcs12");
        trustStore.load(null,null);
        trustStore.setCertificateEntry("ca",trustedCa);
        SSLContextBuilder sslContextBuilder = SSLContexts.custom()
                .loadTrustMaterial(trustStore,null);
        SSLContext sslContext = sslContextBuilder.build();
        RestClientBuilder builder = RestClient.builder(new HttpHost("127.0.0.1", 9200, "https"))
                .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                    @Override
                    public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                        return httpClientBuilder.setSSLContext(sslContext).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                                .setDefaultCredentialsProvider(credentialsProvider);
                    }
                });

        // 创建客户端
        RestClient restClient = builder.build();
        // 通过客户端，创建传输对象
        ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
        // 同步客户端对象
        return new ElasticsearchClient(transport);
    }

    //注入IOC容器
    @Bean
    public ElasticsearchAsyncClient elasticsearchAsyncClient() throws Exception{
        final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        // 声明ES当前登录的账号密码
        credentialsProvider.setCredentials(AuthScope.ANY,new UsernamePasswordCredentials("elastic","4DBHt=M7jxlXDlU47e3F"));
        // 证书的路径
        Path caCertificatePath = Paths.get("E:\\idea_soft\\es8ssl\\src\\main\\resources\\http_ca.crt");
        // x.509 , pkcs12都是 证书的算法
        CertificateFactory factory = CertificateFactory.getInstance("x.509");
        Certificate trustedCa;
        try (InputStream is = Files.newInputStream(caCertificatePath)){
            trustedCa = factory.generateCertificate(is);
        }
        KeyStore trustStore = KeyStore.getInstance("pkcs12");
        trustStore.load(null,null);
        trustStore.setCertificateEntry("ca",trustedCa);
        SSLContextBuilder sslContextBuilder = SSLContexts.custom()
                .loadTrustMaterial(trustStore,null);
        SSLContext sslContext = sslContextBuilder.build();
        RestClientBuilder builder = RestClient.builder(new HttpHost("127.0.0.1", 9200, "https"))
                .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                    @Override
                    public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                        return httpClientBuilder.setSSLContext(sslContext).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                                .setDefaultCredentialsProvider(credentialsProvider);
                    }
                });

        // 创建客户端
        RestClient restClient = builder.build();
        // 通过客户端，创建传输对象
        ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
        // 同步客户端对象
        return new ElasticsearchAsyncClient(transport);
    }
}

